package com.atguigu.springcloud.alibaba.controller;


import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;



/**
 * @Description:
 * Sentinel流控-关联
 * 是什么？
 * 当自己关联的资源达到阈值时，就限流自己
 * 当与A关联的资源B达到阀值后，就限流A自己（B惹事，A挂了）
 *
 * 设置testA
 * 当关联资源/testB的QPS阀值超过1时，就限流/testA的Rest访问地址，当关联资源到阈值后限制配置好的资源名。
 * 实际应用:当支付服务达到阈值,那么就限流下订单的服务,即B快撑不住了,那么就限制调用B的A,即关联
 *
 *
 * Sentinel流控-预热
 * 阈值会变化: 在自己设定的时长内,阈值从峰值的三分之一慢慢的加到顶峰阈值,防止瞬间超大量并发直接干掉服务器
 *
 *
 * 排队等待:
 * 正常是一秒一个请求(设置了阈值是1),如果一秒超过一个请求,那么就排队匀速处理,
 * 如果一秒内的请求在超过了20秒(自己设定)都还没被处理,那么就启动限流
 *
 *
 *
 * @Param:
 * @return:
*/



@RestController
@Slf4j
public class FlowLimitController {
    @GetMapping("/testA")
    public String testA()
    {
//        try {
//            //线程数限流(假设设为1):一次性只能有一个线程进行请求,在该请求没有完成之前,其他的请求将会失败
//            TimeUnit.MILLISECONDS.sleep(800);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        return "------testA";
    }

    @GetMapping("/testB")
    public String testB()
    {
        log.info(Thread.currentThread().getName()+"\t"+"...testB");
        return "------testB";
    }

    @GetMapping("/testD")
    public String testD()
    {
       /* try {
            TimeUnit.MILLISECONDS.sleep(1000);
            log.info(Thread.currentThread().getName()+"\t"+"...testD");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/

//        log.info(Thread.currentThread().getName()+"\t"+"...testD 测试异常比例 ");
        log.info(Thread.currentThread().getName()+"\t"+"...testD 测试分钟异常数 ");
        int a = 10/0;
        return "------testD";
    }


    @GetMapping("/testHotKey")
    @SentinelResource(value = "testHotKey",blockHandler/*兜底方法*/ = "deal_testHotKey")
    public String testHotKey(@RequestParam(value = "p1",required = false) String p1,
                             @RequestParam(value = "p2",required = false) String p2) {
        //int age = 10/0;
        return "------testHotKey--->p1="+p1+"\t"+"p2="+p2;
    }

    /*兜底方法*/
    public String deal_testHotKey (String p1, String p2, BlockException exception) {
        return "------deal_testHotKey,o(╥﹏╥)o";  //sentinel系统默认的提示：Blocked by Sentinel (flow limiting)
    }

}
